{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# langgraph-bigtool\n",
    "\n",
    "[`langgraph-bigtool`](https://github.com/langchain-ai/langgraph-bigtool) is a Python library for creating [LangGraph](https://langchain-ai.github.io/langgraph/) agents that can access large numbers of tools. It leverages LangGraph's long-term [memory store](https://langchain-ai.github.io/langgraph/how-tos/memory/semantic-search/) to allow an agent to search for and retrieve relevant tools for a given problem.\n",
    "\n",
    "## BigTool: Tools \"On-demand\"\n",
    "\n",
    "- Has access to a single retrieval tool initially\n",
    "- Dynamically searches for and retrieves only relevant tools\n",
    "- Only loads what's needed for the specific task\n",
    "\n",
    "![](https://mirror-feeling-d80.notion.site/image/attachment%3Ae0311609-3bf3-43fd-8b41-e18a7414ba8f%3Aimage.png?table=block&id=1c180852-7b17-8011-b804-e6f269ea2a48&spaceId=c2810b1e-a85a-492f-bc51-5aa2decfa5ac&width=1420&userId=&cache=v2)\n",
    "\n",
    "### Benefits\n",
    "\n",
    "- Reasoning load - Reduced cognitive load for the agent\n",
    "- Scalability - can handle hundreds/thousands of tools\n",
    "\n",
    "### vs Multi-agent\n",
    "\n",
    "- **Pro**: Doesn't require putting tools into explicit groups, lower overhead (single agent)\n",
    "- **Con**: If there is an underlying organization of the tools (e.g., into groups), you might be better off representing that explicitly via separate agents (each of which can have distinct system messages, which bigtool also doesn't support).\n",
    "\n",
    "## Features\n",
    "\n",
    "- 🧰 **Scalable access to tools**: Equip agents with hundreds or thousands of tools.\n",
    "- 📝 **Storage of tool metadata**: Control storage of tool descriptions, namespaces, and other information through LangGraph's built-in [persistence layer](https://langchain-ai.github.io/langgraph/concepts/persistence/). Includes support for [in-memory](https://langchain-ai.github.io/langgraph/how-tos/cross-thread-persistence/) and [Postgres](https://langchain-ai.github.io/langgraph/reference/store/#langgraph.store.postgres.PostgresStore) backends.\n",
    "- 💡 **Customization of tool retrieval**: Optionally define custom functions for tool retrieval.\n",
    "\n",
    "This library is built on top of [LangGraph](https://github.com/langchain-ai/langgraph), a powerful framework for building agent applications, and comes with out-of-box support for [streaming](https://langchain-ai.github.io/langgraph/how-tos/#streaming), [short-term and long-term memory](https://langchain-ai.github.io/langgraph/concepts/memory/) and [human-in-the-loop](https://langchain-ai.github.io/langgraph/concepts/human_in_the_loop/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quickstart\n",
    "\n",
    "We demonstrate `langgraph-bigtool` by equipping an agent with all functions from Python's built-in `math` library.\n",
    "\n",
    "> This includes about 50 tools. Some LLMs can handle this number of tools together in a single invocation without issue. This example is for demonstration purposes.\n",
    "\n",
    "We use Ollama for both Chat and Embeddings models.\n",
    "\n",
    "```sh\n",
    "pip install -qU langgraph-bigtool langchain-ollama\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "53"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "import types\n",
    "import uuid\n",
    "\n",
    "from langchain.chat_models import init_chat_model\n",
    "from langchain.embeddings import init_embeddings\n",
    "from langgraph.store.memory import InMemoryStore\n",
    "\n",
    "from langgraph_bigtool import create_agent\n",
    "from langgraph_bigtool.utils import (\n",
    "    convert_positional_only_function_to_tool\n",
    ")\n",
    "\n",
    "# Collect functions from `math` built-in\n",
    "all_tools = []\n",
    "for function_name in dir(math):\n",
    "    function = getattr(math, function_name)\n",
    "    if not isinstance(\n",
    "        function, types.BuiltinFunctionType\n",
    "    ):\n",
    "        continue\n",
    "    # This is an idiosyncrasy of the `math` library\n",
    "    if tool := convert_positional_only_function_to_tool(\n",
    "        function\n",
    "    ):\n",
    "        all_tools.append(tool)\n",
    "\n",
    "# Create registry of tools. This is a dict mapping\n",
    "# identifiers to tool instances.\n",
    "tool_registry = {\n",
    "    str(uuid.uuid4()): tool\n",
    "    for tool in all_tools\n",
    "}\n",
    "\n",
    "len(all_tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# Index tool names and descriptions in the LangGraph\n",
    "# Store. Here we use a simple in-memory store.\n",
    "embeddings = init_embeddings(\"ollama:nomic-embed-text\")\n",
    "\n",
    "store = InMemoryStore(\n",
    "    index={\n",
    "        \"embed\": embeddings,\n",
    "        \"dims\": 256,\n",
    "        \"fields\": [\"description\"],\n",
    "    }\n",
    ")\n",
    "for tool_id, tool in tool_registry.items():\n",
    "    store.put(\n",
    "        (\"tools\",),\n",
    "        tool_id,\n",
    "        {\n",
    "            \"description\": f\"{tool.name}: {tool.description}\",\n",
    "        },\n",
    "    )\n",
    "\n",
    "# Initialize agent\n",
    "llm = init_chat_model(\"ollama:qwen2.5:latest\")\n",
    "\n",
    "builder = create_agent(llm, tool_registry)\n",
    "agent = builder.compile(store=store)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import Image\n",
    "\n",
    "Image(agent.get_graph().draw_mermaid_png())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "Tool Calls:\n",
      "  retrieve_tools (577cd5c8-023d-4a0e-b0a6-68aecc3f540c)\n",
      " Call ID: 577cd5c8-023d-4a0e-b0a6-68aecc3f540c\n",
      "  Args:\n",
      "    query: arc cosine calculator\n",
      "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
      "\n",
      "Available tools: ['acos', 'asin']\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "Tool Calls:\n",
      "  acos (89467a08-4d6a-4cf0-891d-42048c7dc6f8)\n",
      " Call ID: 89467a08-4d6a-4cf0-891d-42048c7dc6f8\n",
      "  Args:\n",
      "    x: 0.5\n",
      "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
      "Name: acos\n",
      "\n",
      "1.0471975511965976\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "The arc cosine of 0.5 is approximately 1.047 radians, which is equivalent to 60 degrees.\n"
     ]
    }
   ],
   "source": [
    "query = \"Use available tools to calculate arc cosine of 0.5.\"\n",
    "\n",
    "# Test it out\n",
    "for step in agent.stream(\n",
    "    {\"messages\": query},\n",
    "    stream_mode=\"updates\",\n",
    "):\n",
    "    for _, update in step.items():\n",
    "        for message in update.get(\"messages\", []):\n",
    "            message.pretty_print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "👆 LangSmith Trace: https://smith.langchain.com/public/75b82ea4-974b-45c1-8f6e-c00d4c1a750f/r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Customizing tool retrieval\n",
    "\n",
    "`langgraph-bigtool` equips an agent with a tool that is used to retrieve tools in the registry. You can customize the retrieval by passing `retrieve_tools_function` and / or `retrieve_tools_coroutine` into `create_agent`. These functions are expected to return a list of IDs as output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph.prebuilt import InjectedStore\n",
    "from langgraph.store.base import BaseStore\n",
    "from typing_extensions import Annotated\n",
    "\n",
    "\n",
    "def retrieve_tools(\n",
    "    query: str,\n",
    "    # Add custom arguments here...\n",
    "    *,\n",
    "    store: Annotated[BaseStore, InjectedStore],\n",
    ") -> list[str]:\n",
    "    \"\"\"Retrieve a tool to use, given a search query.\"\"\"\n",
    "    results = store.search((\"tools\",), query=query, limit=2)\n",
    "    tool_ids = [result.key for result in results]\n",
    "    # Insert your custom logic here...\n",
    "    return tool_ids\n",
    "\n",
    "builder = create_agent(\n",
    "    llm, tool_registry, retrieve_tools_function=retrieve_tools\n",
    ")\n",
    "agent = builder.compile(store=store)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Retrieving tools without LangGraph Store\n",
    "\n",
    "You can implement arbitrary logic for the tool retrieval, which does not have to run semantic search against a query. Below, we return collections of tools corresponding to categories:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tool_registry = {\n",
    "    \"id_1\": get_balance,\n",
    "    \"id_2\": get_history,\n",
    "    \"id_3\": create_ticket,\n",
    "}\n",
    "\n",
    "def retrieve_tools(\n",
    "    category: Literal[\"billing\", \"service\"],\n",
    ") -> list[str]:\n",
    "    \"\"\"Get tools for a category.\"\"\"\n",
    "    if category == \"billing\":\n",
    "        return [\"id_1\", \"id_2\"]\n",
    "    else:\n",
    "        return [\"id_3\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Related work\n",
    "\n",
    "- [Toolshed: Scale Tool-Equipped Agents with Advanced RAG-Tool Fusion and Tool Knowledge Bases](https://doi.org/10.48550/arXiv.2410.14594) - Lumer, E., Subbiah, V.K., Burke, J.A., Basavaraju, P.H. & Huber, A. (2024). arXiv:2410.14594.\n",
    "\n",
    "- [Graph RAG-Tool Fusion](https://doi.org/10.48550/arXiv.2502.07223) - Lumer, E., Basavaraju, P.H., Mason, M., Burke, J.A. & Subbiah, V.K. (2025). arXiv:2502.07223.\n",
    "\n",
    "- https://github.com/quchangle1/LLM-Tool-Survey\n",
    "\n",
    "- [Retrieval Models Aren't Tool-Savvy: Benchmarking Tool Retrieval for Large Language Models](https://doi.org/10.48550/arXiv.2503.01763) - Shi, Z., Wang, Y., Yan, L., Ren, P., Wang, S., Yin, D. & Ren, Z. arXiv:2503.01763."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
